Micron Document
๐ŸŽ–๏ธGitะฏั€ะฐ๐ŸŽ–๏ธ


Displaying Raw โ€ข Download

core/takserver/src/commonMain/kotlin/org/meshtastic/core/takserver/TakMeshTestRunner.kt 65a1f5ce4d0e4b8eafcd0bbfccafd41dc6ee888a (65a1f5ce) Text, 11.13 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tf0883e@fileTb4b4b4:Te6edf3SuppressTb4b4b4(Ta5d6ff"Ta5d6ffTooGenericExceptionCaughtTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffReturnCountTa5d6ff"Tb4b4b4)

Tff7b72package T7ee787org.meshtastic.core.takserver

Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.StateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.asStateFlow
Tff7b72import T7ee787kotlinx.coroutines.sync.Mutex

T8b949e/** Which outbound TAK protocol a [TakTestResult] was dispatched through. See [TAKMeshIntegration]. */
Tff7b72enum Tff7b72class T56d364TakProtocol Tb4b4b4{
T8b949e/** Firmware >= 2.8.0: zstd-compressed TAKPacketV2 on port 78, full typed CoT support. */
Te6edf3V2Tb4b4b4,

T8b949e/** Firmware <= 2.7.x: bare-protobuf legacy TAKPacket on port 72, PLI + GeoChat only. */
Te6edf3V1Tb4b4b4,
Tb4b4b4}

T8b949e/** Result of sending a single test fixture through the TAK mesh pipeline. */
Tff7b72data Tff7b72class T56d364TakTestResultTb4b4b4(
Tff7b72val Te6edf3fixtureNameTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3xmlBytesTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3compressedBytesTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3passedTb4b4b4: Tffa657BooleanTb4b4b4,
Tff7b72val Te6edf3errorTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72val Te6edf3protocolTb4b4b4: Te6edf3TakProtocol Tff7b72= Te6edf3TakProtocolTb4b4b4.Te6edf3V2Tb4b4b4,
T8b949e// Mirrors TakSendOutcome.Dropped.schemaLimited: true only when this fixture was dropped because the active
T8b949e// protocol's CoT type coverage doesn't include it (e.g. v1's TAKPacket only representing PLI/GeoChat) โ€” a
T8b949e// known, permanent limitation of that protocol, so this is expected/intentional behavior, not a self-test
T8b949e// regression. False for an oversize drop (a real MTU problem, even if it happened on v1) or any failure โ€”
T8b949e// never set purely because the result's protocol is V1.
Tff7b72val Te6edf3expectedDropTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Tb4b4b4)

T8b949e/**
* Debug-only test runner that sends the SDK's CoT XML test fixtures through the REAL TAK mesh pipeline: strip โ†’ parse โ†’
* dispatch, via [TAKMeshIntegration.sendCoTToMeshForTest]. Each fixture is run through BOTH the v2 (firmware >= 2.8.0)
* and v1 (legacy) dispatch paths so the self-test's pass/fail rate reflects what a real connected radio would actually
* do on either firmware generation, rather than always exercising the v2 pipeline regardless of the connected radio's
* firmware โ€” see [TAKMeshIntegration.useTakV2].
*
* Paces sends by waiting [sendDelayMs] between each successfully-sent fixture to avoid flooding the radio's TX queue.
* Fixtures that are dropped (not sent) incur no delay.
*/
Tff7b72class T56d364TakMeshTestRunnerTb4b4b4(Tff7b72private Tff7b72val Te6edf3takMeshIntegrationTb4b4b4: Te6edf3TAKMeshIntegrationTb4b4b4) Tb4b4b4{
Tff7b72private Tff7b72val Te6edf3_results Tff7b72= Te6edf3MutableStateFlowTff7b72<Te6edf3ListTff7b72<Te6edf3TakTestResultTff7b72>Tff7b72>Tb4b4b4(Te6edf3emptyListTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3resultsTb4b4b4: Te6edf3StateFlowTff7b72<Te6edf3ListTff7b72<Te6edf3TakTestResultTff7b72>Tff7b72> Tff7b72= Te6edf3_resultsTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72private Tff7b72val Te6edf3_isRunning Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)
Tff7b72val Te6edf3isRunningTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657BooleanTff7b72> Tff7b72= Te6edf3_isRunningTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72private Tff7b72val Te6edf3_currentFixture Tff7b72= Te6edf3MutableStateFlowTff7b72<Tffa657String?Tff7b72>Tb4b4b4(Tff7b72nullTb4b4b4)
Tff7b72val Te6edf3currentFixtureTb4b4b4: Te6edf3StateFlowTff7b72<Tffa657String?Tff7b72> Tff7b72= Te6edf3_currentFixtureTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

T8b949e// Prevents concurrent invocations from racing the _isRunning check-then-set.
Tff7b72private Tff7b72val Te6edf3runMutex Tff7b72= Te6edf3MutexTb4b4b4(Tb4b4b4)

Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e/** Delay between sends to let the radio transmit and receive ACK. */
Tff7b72private Tff7b72const Tff7b72val Te6edf3SEND_DELAY_MS Tff7b72= T79c0ff5Te6edf3_000L

T8b949e/** All bundled fixture filenames. */
Tff7b72val Te6edf3FIXTURE_NAMES Tff7b72=
Te6edf3listOfTb4b4b4(
T8b949e// TAK-Talk sanity test โ€” first in the list so the operator's
T8b949e// initial "Send Test CoTs" tap immediately exercises the
T8b949e// most-stress-tested path on the receiver: m-t-t with
T8b949e// <voice/> push-to-talk marker + <marti> directed routing.
T8b949e// If the receiver's TAKTALK plugin plays a TTS clip for this
T8b949e// single send, the v0.3.2 round-trip pipeline (sender callsign
T8b949e// implicit, marti carried, no spurious <contact>) is wired
T8b949e// end-to-end on both ends of the mesh.
Ta5d6ff"Ta5d6fftaktalk_sanity.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffaircraft_adsb.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffaircraft_hostile.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffalert_tic.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcasevac.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffcasevac_medline.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffchat_receipt_delivered.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffchat_receipt_read.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdelete_event.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_circle.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_circle_large.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_ellipse.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_freeform.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_polygon.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_rectangle.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_rectangle_itak.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffdrawing_telestration.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffemergency_911.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffemergency_cancel.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffgeochat_broadcast.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffgeochat_dm.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffgeochat_simple.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_2525.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_goto.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_goto_itak.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_icon_set.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_spot.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffmarker_tank.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_basic.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_full.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_itak.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_stationary.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_takaware.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffpli_webtak.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffranging_bullseye.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffranging_circle.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffranging_line.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffroute_3wp.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffroute_itak_3wp.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftask_engage.xmlTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffwaypoint.xmlTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

T8b949e/**
* Run all test fixtures sequentially through both the v2 and v1 dispatch paths. Updates [results] and
* [currentFixture] as each fixture is processed. [results] accumulates v2 runs first, then v1 runs.
*/
Tff7b72suspend Tff7b72fun Td2a8ffrunAllTb4b4b4(Tb4b4b4) Tb4b4b4{
T8b949e// Use tryLock to prevent concurrent test runs: if another coroutine is already
T8b949e// inside runAll(), tryLock returns false and we bail immediately. This is safer
T8b949e// than the check-then-set pattern which has a TOCTOU race in multi-threaded
T8b949e// coroutine dispatch.
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3runMutexTb4b4b4.Te6edf3tryLockTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return
Tff7b72try Tb4b4b4{
Te6edf3_isRunningTb4b4b4.Te6edf3value Tff7b72= Tff7b72true
Te6edf3_resultsTb4b4b4.Te6edf3value Tff7b72= Te6edf3emptyListTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3allResults Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3TakTestResultTff7b72>Tb4b4b4(Tb4b4b4)

Tff7b72for Tb4b4b4(Te6edf3protocol Tff7b72in Te6edf3listOfTb4b4b4(Te6edf3TakProtocolTb4b4b4.Te6edf3V2Tb4b4b4, Te6edf3TakProtocolTb4b4b4.Te6edf3V1Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Te6edf3name Tff7b72in Te6edf3FIXTURE_NAMESTb4b4b4) Tb4b4b4{
Te6edf3_currentFixtureTb4b4b4.Te6edf3value Tff7b72= Ta5d6ff"Tffd700$Te6edf3nameTa5d6ff (Tffd700${Te6edf3protocolTb4b4b4.Te6edf3nameTb4b4b4.Te6edf3lowercaseTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff)Ta5d6ff"
Tff7b72val Te6edf3result Tff7b72= Te6edf3runSingleFixtureTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3protocolTb4b4b4)
Te6edf3allResultsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3resultTb4b4b4)
Te6edf3_resultsTb4b4b4.Te6edf3value Tff7b72= Te6edf3allResultsTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3resultTb4b4b4.Te6edf3passedTb4b4b4) Tb4b4b4{
T8b949e// Wait for radio airtime + ACK before next send. Dropped fixtures never
T8b949e// reached the radio, so there's nothing to pace.
Te6edf3delayTb4b4b4(Te6edf3SEND_DELAY_MSTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3_currentFixtureTb4b4b4.Te6edf3value Tff7b72= Tff7b72null

Tff7b72val Te6edf3v2 Tff7b72= Te6edf3allResultsTb4b4b4.Te6edf3filter Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3protocol Tff7b72=Tff7b72= Te6edf3TakProtocolTb4b4b4.Te6edf3V2 Tb4b4b4}
Tff7b72val Te6edf3v1 Tff7b72= Te6edf3allResultsTb4b4b4.Te6edf3filter Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3protocol Tff7b72=Tff7b72= Te6edf3TakProtocolTb4b4b4.Te6edf3V1 Tb4b4b4}
Tff7b72val Te6edf3v2Passed Tff7b72= Te6edf3v2Tb4b4b4.Te6edf3count Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3passed Tb4b4b4}
Tff7b72val Te6edf3v1Passed Tff7b72= Te6edf3v1Tb4b4b4.Te6edf3count Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3passed Tb4b4b4}
Tff7b72val Te6edf3v1ExpectedDrops Tff7b72= Te6edf3v1Tb4b4b4.Te6edf3count Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3expectedDrop Tb4b4b4}
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{
Ta5d6ff"Ta5d6ffTAK Mesh Test complete: v2=Tffd700$Te6edf3v2PassedTa5d6ff/Tffd700${Te6edf3v2Tb4b4b4.Te6edf3sizeTffd700}Ta5d6ff passed; Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffv1=Tffd700$Te6edf3v1PassedTa5d6ff/Tffd700${Te6edf3v1Tb4b4b4.Te6edf3sizeTffd700}Ta5d6ff passed (Tffd700$Te6edf3v1ExpectedDropsTa5d6ff expected drops โ€” Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffv1's legacy schema only supports PLI/GeoChat)Ta5d6ff"
Tb4b4b4}
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3_isRunningTb4b4b4.Te6edf3value Tff7b72= Tff7b72false
Te6edf3runMutexTb4b4b4.Te6edf3unlockTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffrunSingleFixtureTb4b4b4(Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3protocolTb4b4b4: Te6edf3TakProtocolTb4b4b4)Tb4b4b4: Te6edf3TakTestResult Tb4b4b4{
Tff7b72val Te6edf3forceV2 Tff7b72= Te6edf3protocol Tff7b72=Tff7b72= Te6edf3TakProtocolTb4b4b4.Te6edf3V2

T8b949e// Load fixture XML from bundled resources via platform-specific loader
Tff7b72val Te6edf3xml Tff7b72=
Tff7b72try Tb4b4b4{
Te6edf3loadTakFixtureXmlTb4b4b4(Te6edf3nameTb4b4b4)
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3wTb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to load fixture Tffd700$Te6edf3nameTa5d6ff" Tb4b4b4}
Tff7b72return Te6edf3TakTestResultTb4b4b4(Te6edf3nameTb4b4b4, T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4, Tff7b72falseTb4b4b4, Ta5d6ff"Ta5d6ffLoad failed: Tffd700${Te6edf3eTb4b4b4.Te6edf3messageTffd700}Ta5d6ff"Tb4b4b4, Te6edf3protocolTb4b4b4)
Tb4b4b4}

T8b949e// Parse into the same CoTMessage shape a real inbound TAK-client message would produce
T8b949e// (sourceEventXml preserved) โ€” see CoTXmlParser.buildCoTMessage.
Tff7b72val Te6edf3cotMessage Tff7b72=
Te6edf3CoTXmlParserTb4b4b4(Te6edf3xmlTb4b4b4)Tb4b4b4.Te6edf3parseTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3getOrElse Tb4b4b4{ Te6edf3e Tff7b72-Tff7b72>
Te6edf3LoggerTb4b4b4.Te6edf3wTb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Test: Tffd700$Te6edf3nameTa5d6ff failed to parse as CoT XML: Tffd700${Te6edf3eTb4b4b4.Te6edf3messageTffd700}Ta5d6ff" Tb4b4b4}
Tff7b72return Te6edf3TakTestResultTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3xmlTb4b4b4.Te6edf3lengthTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72falseTb4b4b4, Ta5d6ff"Ta5d6ffParse failed: Tffd700${Te6edf3eTb4b4b4.Te6edf3messageTffd700}Ta5d6ff"Tb4b4b4, Te6edf3protocolTb4b4b4)
Tb4b4b4}

T8b949e// Dispatch through the REAL production pipeline (TAKMeshIntegration.sendCoTToMeshV1/V2),
T8b949e// with the protocol forced rather than read from the connected radio's firmware.
Tff7b72return Tff7b72try Tb4b4b4{
Tff7b72when Tb4b4b4(Tff7b72val Te6edf3outcome Tff7b72= Te6edf3takMeshIntegrationTb4b4b4.Te6edf3sendCoTToMeshForTestTb4b4b4(Te6edf3cotMessageTb4b4b4, Te6edf3forceV2Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3TakSendOutcomeTb4b4b4.Te6edf3Sent Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Test: Tffd700$Te6edf3nameTa5d6ff โ†’ Tffd700${Te6edf3outcomeTb4b4b4.Te6edf3wireBytesTffd700}Ta5d6ffB (xml=Tffd700${Te6edf3xmlTb4b4b4.Te6edf3lengthTffd700}Ta5d6ffB) via Tffd700$Te6edf3protocolTa5d6ff" Tb4b4b4}
Te6edf3TakTestResultTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3xmlTb4b4b4.Te6edf3lengthTb4b4b4, Te6edf3outcomeTb4b4b4.Te6edf3wireBytesTb4b4b4, Tff7b72trueTb4b4b4, Te6edf3protocol Tff7b72= Te6edf3protocolTb4b4b4)
Tb4b4b4}

Tff7b72is Te6edf3TakSendOutcomeTb4b4b4.Te6edf3Dropped Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Test: Tffd700$Te6edf3nameTa5d6ff dropped on Tffd700$Te6edf3protocolTa5d6ff: Tffd700${Te6edf3outcomeTb4b4b4.Te6edf3reasonTffd700}Ta5d6ff" Tb4b4b4}
Te6edf3TakTestResultTb4b4b4(
Te6edf3fixtureName Tff7b72= Te6edf3nameTb4b4b4,
Te6edf3xmlBytes Tff7b72= Te6edf3xmlTb4b4b4.Te6edf3lengthTb4b4b4,
Te6edf3compressedBytes Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3passed Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3error Tff7b72= Te6edf3outcomeTb4b4b4.Te6edf3reasonTb4b4b4,
Te6edf3protocol Tff7b72= Te6edf3protocolTb4b4b4,
T8b949e// Only a schema-coverage drop is an expected/intentional limitation (v1's legacy
T8b949e// schema legitimately supports only PLI/GeoChat). An oversize drop is a real MTU
T8b949e// problem regardless of which protocol hit it, and must never be mislabeled as
T8b949e// expected just because it happened on v1.
Te6edf3expectedDrop Tff7b72= Te6edf3outcomeTb4b4b4.Te6edf3schemaLimitedTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tff7b72is Te6edf3TakSendOutcomeTb4b4b4.Te6edf3Failed Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Test: Tffd700$Te6edf3nameTa5d6ff send failed on Tffd700$Te6edf3protocolTa5d6ff: Tffd700${Te6edf3outcomeTb4b4b4.Te6edf3reasonTffd700}Ta5d6ff" Tb4b4b4}
Te6edf3TakTestResultTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3xmlTb4b4b4.Te6edf3lengthTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72falseTb4b4b4, Te6edf3outcomeTb4b4b4.Te6edf3reasonTb4b4b4, Te6edf3protocolTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4: Te6edf3kotlinTb4b4b4.Te6edf3coroutinesTb4b4b4.Te6edf3cancellationTb4b4b4.Te6edf3CancellationExceptionTb4b4b4) Tb4b4b4{
Tff7b72throw Te6edf3e
Tb4b4b4} Tff7b72catch Tb4b4b4(Te6edf3eTb4b4b4: Te6edf3ExceptionTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3wTb4b4b4(Te6edf3eTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffTAK Test: Tffd700$Te6edf3nameTa5d6ff send failed: Tffd700${Te6edf3eTb4b4b4.Te6edf3messageTffd700}Ta5d6ff" Tb4b4b4}
Te6edf3TakTestResultTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3xmlTb4b4b4.Te6edf3lengthTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72falseTb4b4b4, Ta5d6ff"Ta5d6ffSend failed: Tffd700${Te6edf3eTb4b4b4.Te6edf3messageTffd700}Ta5d6ff"Tb4b4b4, Te6edf3protocolTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.09s